package com.bee.sample.ch2.conf;

import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.gson.Gson;

/**
 * Controller 的所有方法在执行前后都会进入functionAccessCheck方法
 * 
 * @author lijiazhi
 *
 */
@Aspect
@Configuration
public class AOPConfig {
	@Around("@within(org.springframework.stereotype.Controller) ")
	public Object functionAccessCheck(final ProceedingJoinPoint pjp) throws Throwable {
		try {
			Object[] args = pjp.getArgs();
			System.out.println("args:" + Arrays.asList(args));
			Object o = pjp.proceed();
			System.out.println("return :" + o);
			return o;
		} catch (Throwable e) {
			throw e;
		}
	}

	private Logger log = LoggerFactory.getLogger(getClass());
	private Gson gson = new Gson();
	ThreadLocal<Long> startTime = new ThreadLocal<Long>();

	// 申明一个切点 里面是 execution表达式
	@Pointcut("execution(public * com.bee.sample.ch2.controller..*.*(..)) ")
	/*
	 * 1）execution(* *(..)) //表示匹配所有方法 2）execution(public * com.
	 * savage.service.UserService.*(..))
	 * //表示匹配com.savage.server.UserService中所有的公有方法 3）execution(*
	 * com.savage.server..*.*(..)) //表示匹配com.savage.server包及其子包下的所有方法
	 */

	private void controllerAspect() {
	}

	// 请求method前打印内容
	@Before(value = "controllerAspect()")
	public void methodBefore(JoinPoint joinPoint) {
		startTime.set(System.currentTimeMillis());
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		// 打印请求内容
		log.info("===============请求内容===============");
		log.info("请求地址:" + request.getRequestURL().toString());
		log.info("请求方式:" + request.getMethod());
		log.info("请求类方法:" + joinPoint.getSignature());
		log.info("请求类方法参数:" + Arrays.toString(joinPoint.getArgs()));
		log.info("===============请求内容===============");
	}

	// 在方法执行完结后打印返回内容
	@AfterReturning(returning = "o", pointcut = "controllerAspect()")
	public void methodAfterReturing(Object o) {
		log.info("--------------返回内容----------------");
		log.info("Response内容:" + gson.toJson(o));
		log.info("--------------返回内容----------------");
		log.info("请求处理时间为:" + (System.currentTimeMillis() - startTime.get()));
	}
	
	
}
